const path = require('path');
const fs = require('fs');
const util = require('util');
const defaultConfig = require('./defaultConfig');
const fontLoader = require.resolve("./font-loader");
const jsLoader = require.resolve("./js-loader");
const pkgName = require('../package.json').name;
let pluginConfig = {};

const utils = {
  isDevelop() {
    return process.env.NODE_ENV !== 'production';
  },

  /**
    *
    * @param fn {Function}   实际要执行的函数
    * @param delay {Number}  延迟时间，也就是阈值，单位是毫秒（ms）
    * @return {Function}     返回一个“去弹跳”了的函数
    */
  debounce(fn, delay) {
    // 定时器，用来 setTimeout
    let timer;
    // 返回一个函数，这个函数会在一个时间区间结束后的 delay 毫秒时执行 fn 函数
    return function (...args) {
      // 每次这个返回的函数被调用，就清除定时器，以保证不执行 fn
      clearTimeout(timer);
      // 当返回的函数被最后一次调用后（也就是用户停止了某个连续的操作），
      // 再过 delay 毫秒就执行 fn
      timer = setTimeout(() => {
        fn.apply(this, args)
      }, delay);
    }
  },

  getTmpDir() {
    return path.join('node_modules', '.cache', pkgName, utils.isDevelop() ? 'dev' : 'pro');
  },

  /**
   * 获取svg图标下载的路径
   * 开发环境和生产环境不一样
   */
  getSvgPath() {
    const dir = utils.getTmpDir();
    return path.join(dir, `svg`);
  },

  mkdir(dir) {
    return new Promise(function (resolve, reject) {
      fs.mkdir(dir, { recursive: true }, err => {
        if (err) {
          console.log(err)
        }
        resolve()
      });
    });
  },

  mkdirSync(dir) {
    try {
      fs.mkdirSync(dir, { recursive: true });
    } catch (e) {
    }
  },

  /**
   * 记录数据到临时文件
   * @param str
   */
  saveTemp(filename, str) {
    try {
      const dir = utils.getTmpDir();
      utils.mkdirSync(dir);
      const tmpEntryFilePath = path.join(dir, filename);
      // const writeFile = util.promisify(fs.writeFile);
      fs.writeFileSync(tmpEntryFilePath, str.toString(), 'utf8');
    } catch (e) {
      console.log(e);
    }
  },

  /**
  * 从临时文件读取数据
  */
  getTemp(filename) {
    try {
      const dir = utils.getTmpDir();
      // const readFile = util.promisify(fs.readFile);
      return fs.readFileSync(path.join(dir, filename), 'utf8');
    } catch (e) {

    }
  },

  /**
   * 记录webpack的入口文件
   * @param {Array} arr 绝对地址
   */
  saveTempEntry(arr) {
    process.env.KISS_FONT__TEMP__ENTRY = JSON.stringify(arr);
  },

  /**
   * 读取webpack的入口文件
   * @return {Array}
   */
  getTempEntry() {
    let entry = process.env.KISS_FONT__TEMP__ENTRY;
    if (entry) {
      return JSON.parse(entry);
    }
  },

  /**
   * 读取目录下文件
   * @returns 包含目录的名称
   */
  async getFilesByDir(dir, fileType) {
    const readdir = util.promisify(fs.readdir);
    try {
      const files = await readdir(dir);
      let arr = [];
      files.forEach((name) => {
        if (!fileType || name.endsWith(fileType)) {
          arr.push(path.join(dir, name));
        }
      });
      return arr;
    } catch (e) {
      return [];
    }
  },

  setPluginConfig(config) {
    if (config) {
      pluginConfig = config;
    }
  },
  getPluginConfig() {
    return pluginConfig;
  },
  /**
   * 获取合并后的配置信息
   * 优先级为：kiss.font.config.js > loader.options > plugin.options > 默认config配置
   * @param {Boolean} isExistConfig 是否存在配置文件
   * @param {Object} loaderOptions 通过loader传递进来的配置信息
   */
  getConfig(isExistConfig, loaderOptions = {}) {
    const CONFIG_NAME = defaultConfig.configName;
    if (isExistConfig === undefined) {
      isExistConfig = fs.existsSync(CONFIG_NAME);
    }
    if (isExistConfig) {
      const dir = path.resolve(CONFIG_NAME);
      const config = require(dir);
      return Object.assign({}, defaultConfig, pluginConfig, loaderOptions, config);
    }
    return Object.assign({}, defaultConfig, pluginConfig, loaderOptions);
  },
  clearRequireCache(dir) {
    // console.log('----------del----------');
    delete require.cache[require.resolve(dir)];
  },
  clearRequireConfigCache() {
    const CONFIG_NAME = defaultConfig.configName;
    const isExistConfig = fs.existsSync(CONFIG_NAME);
    if (isExistConfig) {
      const p = `./${CONFIG_NAME}`;
      const dir = path.resolve(p);
      utils.clearRequireCache(dir);
    }
  },
  getTempCssDir() {
    return path.resolve(__dirname, '../tmp');
  },
  /**
  * 提供vue.config中配置webpack
  */
  chainWebpack(config, options = {}) {
    const jsLoaderOptions = { isAutoJnjectComponent: true, ...options };
    const fontConfig = utils.getConfig(false); //只为取cssFileName

    config.module.rule(fontConfig.isTs ? 'ts' : 'js').use(jsLoader).loader(jsLoader).options(jsLoaderOptions).end();

    const vueRule = config.module.rule('vue');
    if (!utils.isDevelop()) { //生产环境
      vueRule.uses.delete('cache-loader');
    }

    const tempDir = utils.getTempCssDir();
    utils.mkdirSync(tempDir);
    fs.writeFileSync(path.join(tempDir, fontConfig.cssFileName + '.css'), `.uk {}`);

    const fontCssReg = new RegExp(`${fontConfig.cssFileName}\\.css`);
    config.module.rule('css').exclude.store.add(fontCssReg);
    config.module.rule('fontcss').test(fontCssReg)
      .use('style-loader').loader('style-loader').options({ injectType: 'styleTag' }).end()
      .use('css-loader').loader('css-loader').end();
    //代理临时目录
    // config.devServer.contentBase(utils.getTmpDir());
  }
};

module.exports = utils;
